#include "boardstate.h"

BoardState::BoardState()
{
    if (_turn == WHITE){
        _wPawnAdvancedTwo = -1; // no white pawn has advanced two squares
    } else {
        _bPawnAdvancedTwo = -1; // no black pawn has advanced two squares
    }
	_wCastleShortAllowed = true;
	_wCastleLongAllowed = true;
	_bCastleShortAllowed = true;
	_bCastleLongAllowed = true;
}

BoardState::~BoardState()
{
    //dtor
}

int BoardState::getPiece(int x, int y)
{
    return _board[x][y];
}

void BoardState::clear()
{
    for(int y = 0; y < 8; ++y) {
        for(int x = 0; x < 8; ++x) {
            _board[x][y] = EMPTY;
        }
    }
}

void BoardState::initPos()
{
    _board[0][0] = B_ROOK;
    _board[1][0] = B_KNIGHT;
    _board[2][0] = B_BISHOP;
    _board[3][0] = B_QUEEN;
    _board[4][0] = B_KING;
    _board[5][0] = B_BISHOP;
    _board[6][0] = B_KNIGHT;
    _board[7][0] = B_ROOK;

    for(int i=0; i<8; i++) {
        _board[i][1] = B_PAWN;
    }
    for(int i=0; i<8; i++) {
        _board[i][6] = W_PAWN;
    }

    _board[0][7] = W_ROOK;
    _board[1][7] = W_KNIGHT;
    _board[2][7] = W_BISHOP;
    _board[3][7] = W_QUEEN;
    _board[4][7] = W_KING;
    _board[5][7] = W_BISHOP;
    _board[6][7] = W_KNIGHT;
    _board[7][7] = W_ROOK;

    _turn = WHITE;
    _wKingPosition[0] = 4;
    _wKingPosition[1] = 7;
    _bKingPosition[0] = 4;
    _bKingPosition[1] = 0;
    _wPawnAdvancedTwo = -1; // white pawn advanced two at this line (0-7)
    _bPawnAdvancedTwo = -1; // -1 -> not at any line
    _wCastleShortAllowed = true;
	_wCastleLongAllowed = true;
	_bCastleShortAllowed = true;
	_bCastleLongAllowed = true;

}

void BoardState::print() const
{
    int x, y;
    std::cout << std::endl << "    A   B   C   D   E   F   G   H" << std::endl;
    for(y=0; y<8; y++) {
        std::cout << "  +---+---+---+---+---+---+---+---+" << std::endl;
        std::cout << (8-y) << " |";
        for(x=0; x<8; x++) {
            if (_board[x][y] == W_KING) { std::cout << " k "; }
            else if (_board[x][y] == B_KING) { std::cout << " K "; }
            else if (_board[x][y] == W_QUEEN) { std::cout << " q "; }
            else if (_board[x][y] == B_QUEEN) { std::cout << " Q "; }
            else if (_board[x][y] == W_ROOK) { std::cout << " r "; }
            else if (_board[x][y] == B_ROOK) { std::cout << " R "; }
            else if (_board[x][y] == W_BISHOP) { std::cout << " b "; }
            else if (_board[x][y] == B_BISHOP) { std::cout << " B "; }
            else if (_board[x][y] == W_KNIGHT) { std::cout << " n "; }
            else if (_board[x][y] == B_KNIGHT) { std::cout << " N "; }
            else if (_board[x][y] == W_PAWN) { std::cout << " p "; }
            else if (_board[x][y] == B_PAWN) { std::cout << " P "; }
            else {std::cout << "   ";}
            std::cout << "|";
        }
        std::cout << " " << (8-y) << std::endl;
    }
    std::cout << "  +---+---+---+---+---+---+---+---+" << std::endl;
    std::cout << "    A   B   C   D   E   F   G   H" << std::endl;
}

bool BoardState::execMove(const Move &m)
{
    bool captured = false;
    if(_board[m.getX2()][m.getY2()] != EMPTY){
        captured = true;
    }
    if (m.getSpecialRule() == NONE) {

        // Set caste flags and update king position
        if (_board[m.getX1()][m.getY1()] == W_KING){
            _wCastleShortAllowed = false;
            _wCastleLongAllowed = false;
            _wKingPosition[0] = m.getX2();
            _wKingPosition[1] = m.getY2();
        } else if (_board[m.getX1()][m.getY1()] == B_KING){
            _bCastleShortAllowed = false;
            _bCastleLongAllowed = false;
            _bKingPosition[0] = m.getX2();
            _bKingPosition[1] = m.getY2();
        } else if ((m.getX1() == 0 && m.getY1() == 0) ||
                   (m.getX2() == 0 && m.getY2() == 0)){ //rook left-up corner
            _bCastleLongAllowed = false;
        } else if ((m.getX1() == 7 && m.getY1() == 0) ||
                   (m.getX2() == 7 && m.getY2() == 0)){ //rook right-up corner
            _bCastleShortAllowed = false;
        } else if ((m.getX1() == 0 && m.getY1() == 7) ||
                   (m.getX2() == 0 && m.getY2() == 7)){ //rook left-down corner
            _wCastleLongAllowed = false;
        } else if ((m.getX1() == 7 && m.getY1() == 7) ||
                   (m.getX2() == 7 && m.getY2() == 7)){ //rook right-down corner
            _wCastleShortAllowed = false;
        }

        // Execute the move
        _board[m.getX2()][m.getY2()] = _board[m.getX1()][m.getY1()];
        _board[m.getX1()][m.getY1()] = EMPTY;

        // Set passat flags
        if(_board[m.getX2()][m.getY2()] == W_PAWN && (m.getY1() - m.getY2() == 2)) {
            _wPawnAdvancedTwo = m.getX1();
        } else if(_board[m.getX2()][m.getY2()] == B_PAWN && (m.getY2() - m.getY1() == 2)) {
            _bPawnAdvancedTwo = m.getX1();
        } else {
            if (_turn == WHITE){
                _wPawnAdvancedTwo = -1;
            } else { // BLACK
                _bPawnAdvancedTwo = -1;
            }
        }

    } else if (m.getSpecialRule() == CASTLESHORT) { // Execute castleshort move
        if (_turn == WHITE){
            _board[6][7] = W_KING;
            _board[4][7] = EMPTY;
            _board[5][7] = W_ROOK;
            _board[7][7] = EMPTY;
            _wCastleShortAllowed = false;
            _wCastleLongAllowed = false;
            _wKingPosition[0] = 6;
        } else {
            _board[6][0] = B_KING;
            _board[4][0] = EMPTY;
            _board[5][0] = B_ROOK;
            _board[7][0] = EMPTY;
            _bCastleShortAllowed = false;
            _bCastleLongAllowed = false;
            _bKingPosition[0] = 6;
        }
    } else if (m.getSpecialRule() == CASTLELONG) { // Execute castlelong move
        if (_turn == WHITE){
            _board[2][7] = W_KING;
            _board[4][7] = EMPTY;
            _board[3][7] = W_ROOK;
            _board[0][7] = EMPTY;
            _wCastleShortAllowed = false;
            _wCastleLongAllowed = false;
            _wKingPosition[0] = 2;
        } else {
            _board[2][0] = B_KING;
            _board[4][0] = EMPTY;
            _board[3][0] = B_ROOK;
            _board[0][0] = EMPTY;
            _bCastleShortAllowed = false;
            _bCastleLongAllowed = false;
            _bKingPosition[0] = 2;
        }
    } else if (m.getSpecialRule() == PASSAT) { // Execute passat move
        _board[m.getX2()][m.getY2()] = _board[m.getX1()][m.getY1()];
        _board[m.getX1()][m.getY1()] = EMPTY;
        if (_turn == WHITE) {
             _board[m.getX2()][m.getY2()+1]  = EMPTY;
        } else {
            _board[m.getX2()][m.getY2()-1]  = EMPTY;
        }
    } else { //Execute pawn move and promote to QUEEN, ROOK, BISHOP or KNIGHT
        if (_turn == WHITE){
            if (m.getSpecialRule() == ROOK){
                _board[m.getX2()][m.getY2()] = W_ROOK;
            } else if (m.getSpecialRule() == BISHOP){
                _board[m.getX2()][m.getY2()] = W_BISHOP;
            } else if (m.getSpecialRule() == KNIGHT){
                _board[m.getX2()][m.getY2()] = W_KNIGHT;
            } else if (m.getSpecialRule() == QUEEN){
                _board[m.getX2()][m.getY2()] = W_QUEEN;
            }
        } else { // black's turn
            if (m.getSpecialRule() == ROOK){
                _board[m.getX2()][m.getY2()] = B_ROOK;
            } else if (m.getSpecialRule() == BISHOP){
                _board[m.getX2()][m.getY2()] = B_BISHOP;
            } else if (m.getSpecialRule() == KNIGHT){
                _board[m.getX2()][m.getY2()] = B_KNIGHT;
            } else if (m.getSpecialRule() == QUEEN){
                _board[m.getX2()][m.getY2()] = B_QUEEN;
            }
        }
        _board[m.getX1()][m.getY1()] = EMPTY;
    }

    // Switch turns
    if (_turn == WHITE){
        _turn = BLACK;
    } else { // black's turn
        _turn = WHITE;
    }

    return captured;
}

void BoardState::modifyHelpBoard(const Move &m)
{
    if (m.getSpecialRule() == NONE) {

        // Update king position
        if (_helpBoard[m.getX1()][m.getY1()] == W_KING){
            _helpWKingPosition[0] = m.getX2();
            _helpWKingPosition[1] = m.getY2();
        } else if (_helpBoard[m.getX1()][m.getY1()] == B_KING){
            _helpBKingPosition[0] = m.getX2();
            _helpBKingPosition[1] = m.getY2();
        }

        // Execute the move
        _helpBoard[m.getX2()][m.getY2()] = _helpBoard[m.getX1()][m.getY1()];
        _helpBoard[m.getX1()][m.getY1()] = EMPTY;

    } else if (m.getSpecialRule() == CASTLESHORT) { // Execute castleshort move
        if (_turn == WHITE){
            _helpBoard[6][7] = W_KING;
            _helpBoard[4][7] = EMPTY;
            _helpBoard[5][7] = W_ROOK;
            _helpBoard[7][7] = EMPTY;
            _helpWKingPosition[0] = 6;
        } else {
            _helpBoard[6][0] = B_KING;
            _helpBoard[4][0] = EMPTY;
            _helpBoard[5][0] = B_ROOK;
            _helpBoard[7][0] = EMPTY;
            _helpBKingPosition[0] = 6;
        }
    } else if (m.getSpecialRule() == CASTLELONG) { // Execute castlelong move
        if (_turn == WHITE){
            _helpBoard[2][7] = W_KING;
            _helpBoard[4][7] = EMPTY;
            _helpBoard[3][7] = W_ROOK;
            _helpBoard[0][7] = EMPTY;
            _helpWKingPosition[0] = 2;
        } else {
            _helpBoard[2][0] = B_KING;
            _helpBoard[4][0] = EMPTY;
            _helpBoard[3][0] = B_ROOK;
            _helpBoard[0][0] = EMPTY;
            _helpBKingPosition[0] = 2;
        }
    } else if (m.getSpecialRule() == PASSAT) { // Execute passat move
        _helpBoard[m.getX2()][m.getY2()] = _helpBoard[m.getX1()][m.getY1()];
        _helpBoard[m.getX1()][m.getY1()] = EMPTY;
        if (_turn == WHITE) {
             _helpBoard[m.getX2()][m.getY2()+1]  = EMPTY;
        } else {
            _helpBoard[m.getX2()][m.getY2()-1]  = EMPTY;
        }
    }
}

void BoardState::setTurn(int color)
{
    _turn = color;
}

int BoardState::getTurn()
{
    return _turn;
}

int BoardState::genLegalMoves(Move *moveList)
{
    int countMoves = 0;
    if (_turn == WHITE){
        for (int y = 0; y < 8; ++y) {
            for (int x = 0; x < 8; ++x) {
                if (_board[x][y] == W_PAWN) {
                    genLegalMovesWPawn(moveList, x, y, &countMoves);
                } else if (_board[x][y] == W_QUEEN) {
                    genLegalMovesWQueen(moveList, x, y, &countMoves);
                } else if (_board[x][y] == W_KNIGHT) {
                    genLegalMovesWKnight(moveList, x, y, &countMoves);
                } else if (_board[x][y] == W_BISHOP) {
                    genLegalMovesWBishop(moveList, x, y, &countMoves);
                } else if (_board[x][y] == W_ROOK) {
                    genLegalMovesWRook(moveList, x, y, &countMoves);
                } else if (_board[x][y] == W_KING) {
                    genLegalMovesWKing(moveList, x, y, &countMoves);
                }
            }
        }
        isCheckW(moveList, &countMoves);
    } else { //black's turn
        for (int y = 0; y < 8; ++y) {
            for (int x = 0; x < 8; ++x) {
                if (_board[x][y] == B_PAWN) {
                    genLegalMovesBPawn(moveList, x, y, &countMoves);
                } else if (_board[x][y] == B_QUEEN) {
                    genLegalMovesBQueen(moveList, x, y, &countMoves);
                } else if (_board[x][y] == B_KNIGHT) {
                    genLegalMovesBKnight(moveList, x, y, &countMoves);
                } else if (_board[x][y] == B_BISHOP) {
                    genLegalMovesBBishop(moveList, x, y, &countMoves);
                } else if (_board[x][y] == B_ROOK) {
                    genLegalMovesBRook(moveList, x, y, &countMoves);
                } else if (_board[x][y] == B_KING) {
                    genLegalMovesBKing(moveList, x, y, &countMoves);
                }
            }
        }
        isCheckB(moveList, &countMoves);
    }
    return countMoves; // returns amount of legal moves found
}


void BoardState::isCheckW(Move *moveList, int *countMoves)
{
    int x, y;
    for (int i = (*countMoves)-1; i >= 0 ; --i) {
        // clone _board to _helpBoard
        for(y = 0; y < 8; ++y) {
            for(int x = 0; x < 8; ++x) {
                _helpBoard[x][y] = _board[x][y];
            }
        }
        _helpWKingPosition[0] = _wKingPosition[0];
        _helpWKingPosition[1] = _wKingPosition[1];
        modifyHelpBoard(moveList[i]);

        // Knight
        x = _helpWKingPosition[0] + 2;
        y = _helpWKingPosition[1] + 1;
        if (x >= 0 && x < 8 && y >= 0 && y < 8 && _helpBoard[x][y] == B_KNIGHT) {
            if (i != *countMoves - 1){
               moveList[i] = moveList[*countMoves - 1];
            }
            --(*countMoves);
            continue;
        }
        x = _helpWKingPosition[0] + 2;
        y = _helpWKingPosition[1] - 1;
        if (x >= 0 && x < 8 && y >= 0 && y < 8 && _helpBoard[x][y] == B_KNIGHT) {
            if (i != *countMoves - 1){
               moveList[i] = moveList[*countMoves - 1];
            }
            --(*countMoves);
            continue;
        }
        x = _helpWKingPosition[0] - 2;
        y = _helpWKingPosition[1] + 1;
        if (x >= 0 && x < 8 && y >= 0 && y < 8 && _helpBoard[x][y] == B_KNIGHT) {
            if (i != *countMoves - 1){
               moveList[i] = moveList[*countMoves - 1];
            }
            --(*countMoves);
            continue;
        }
        x = _helpWKingPosition[0] - 2;
        y = _helpWKingPosition[1] - 1;
        if (x >= 0 && x < 8 && y >= 0 && y < 8 && _helpBoard[x][y] == B_KNIGHT) {
            if (i != *countMoves - 1){
               moveList[i] = moveList[*countMoves - 1];
            }
            --(*countMoves);
            continue;
        }
        x = _helpWKingPosition[0] + 1;
        y = _helpWKingPosition[1] + 2;
        if (x >= 0 && x < 8 && y >= 0 && y < 8 && _helpBoard[x][y] == B_KNIGHT) {
            if (i != *countMoves - 1){
               moveList[i] = moveList[*countMoves - 1];
            }
            --(*countMoves);
            continue;
        }
        x = _helpWKingPosition[0] + 1;
        y = _helpWKingPosition[1] - 2;
        if (x >= 0 && x < 8 && y >= 0 && y < 8 && _helpBoard[x][y] == B_KNIGHT) {
            if (i != *countMoves - 1){
               moveList[i] = moveList[*countMoves - 1];
            }
            --(*countMoves);
            continue;
        }
        x = _helpWKingPosition[0] - 1;
        y = _helpWKingPosition[1] + 2;
        if (x >= 0 && x < 8 && y >= 0 && y < 8 && _helpBoard[x][y] == B_KNIGHT) {
            if (i != *countMoves - 1){
               moveList[i] = moveList[*countMoves - 1];
            }
            --(*countMoves);
            continue;
        }
        x = _helpWKingPosition[0] - 1;
        y = _helpWKingPosition[1] - 2;
        if (x >= 0 && x < 8 && y >= 0 && y < 8 && _helpBoard[x][y] == B_KNIGHT) {
            if (i != *countMoves - 1){
               moveList[i] = moveList[*countMoves - 1];
            }
            --(*countMoves);
            continue;
        }

        //Queen, Bishop & Rook
        bool skipRest = false;

        // East
        x = _helpWKingPosition[0] + 1;
        y = _helpWKingPosition[1];
        while (x < 8) {
            if (_helpBoard[x][y] == EMPTY) {
                ++x;
            } else if (_helpBoard[x][y] == B_QUEEN || _helpBoard[x][y] == B_ROOK) {
                if (i != *countMoves - 1){
                   moveList[i] = moveList[*countMoves - 1];
                }
                --(*countMoves);
                skipRest = true;
                break;
            } else {
                break;
            }
        }
        if(skipRest) {
            continue;
        }

        // West
        x = _helpWKingPosition[0] - 1;
        y = _helpWKingPosition[1];
        while (x >= 0) {
            if (_helpBoard[x][y] == EMPTY) {
                --x;
            } else if (_helpBoard[x][y] == B_QUEEN || _helpBoard[x][y] == B_ROOK) {
                if (i != *countMoves - 1){
                   moveList[i] = moveList[*countMoves - 1];
                }
                --(*countMoves);
                skipRest = true;
                break;
            } else {
                break;
            }
        }
        if(skipRest) {
            continue;
        }

        // South
        x = _helpWKingPosition[0];
        y = _helpWKingPosition[1] + 1;
        while (y < 8) {
            if (_helpBoard[x][y] == EMPTY) {
                ++y;
            } else if (_helpBoard[x][y] == B_QUEEN || _helpBoard[x][y] == B_ROOK) {
                if (i != *countMoves - 1){
                   moveList[i] = moveList[*countMoves - 1];
                }
                --(*countMoves);
                skipRest = true;
                break;
            } else {
                break;
            }
        }
        if(skipRest) {
            continue;
        }

        // North
        x = _helpWKingPosition[0];
        y = _helpWKingPosition[1] - 1;
        while (y >= 0) {
            if (_helpBoard[x][y] == EMPTY) {
                --y;
            } else if (_helpBoard[x][y] == B_QUEEN || _helpBoard[x][y] == B_ROOK) {
                if (i != *countMoves - 1){
                   moveList[i] = moveList[*countMoves - 1];
                }
                --(*countMoves);
                skipRest = true;
                break;
            } else {
                break;
            }
        }
        if(skipRest) {
            continue;
        }

        // North-East
        x = _helpWKingPosition[0] + 1;
        y = _helpWKingPosition[1] - 1;
        while (x < 8 && y >= 0) {
            if (_helpBoard[x][y] == EMPTY) {
                ++x;
                --y;
            } else if (_helpBoard[x][y] == B_QUEEN || _helpBoard[x][y] == B_BISHOP) {
                if (i != *countMoves - 1){
                   moveList[i] = moveList[*countMoves - 1];
                }
                --(*countMoves);
                skipRest = true;
                break;
            } else {
                break;
            }
        }
        if(skipRest) {
            continue;
        }

        // South-East
        x = _helpWKingPosition[0] + 1;
        y = _helpWKingPosition[1] + 1;
        while (x < 8 && y < 8) {
            if (_helpBoard[x][y] == EMPTY) {
                ++x;
                ++y;
            } else if (_helpBoard[x][y] == B_QUEEN || _helpBoard[x][y] == B_BISHOP) {
                if (i != *countMoves - 1){
                   moveList[i] = moveList[*countMoves - 1];
                }
                --(*countMoves);
                skipRest = true;
                break;
            } else {
                break;
            }
        }
        if(skipRest) {
            continue;
        }

        // North-West
        x = _helpWKingPosition[0] - 1;
        y = _helpWKingPosition[1] - 1;
        while (x >= 0 && y >= 0) {
            if (_helpBoard[x][y] == EMPTY) {
                --x;
                --y;
            } else if (_helpBoard[x][y] == B_QUEEN || _helpBoard[x][y] == B_BISHOP) {
                if (i != *countMoves - 1){
                   moveList[i] = moveList[*countMoves - 1];
                }
                --(*countMoves);
                skipRest = true;
                break;
            } else {
                break;
            }
        }
        if(skipRest) {
            continue;
        }

        // South-West
        x = _helpWKingPosition[0] - 1;
        y = _helpWKingPosition[1] + 1;
        while (x >= 0 && y < 8) {
            if (_helpBoard[x][y] == EMPTY) {
                --x;
                ++y;
            } else if (_helpBoard[x][y] == B_QUEEN || _helpBoard[x][y] == B_BISHOP) {
                if (i != *countMoves - 1){
                   moveList[i] = moveList[*countMoves - 1];
                }
                --(*countMoves);
                skipRest = true;
                break;
            } else {
                break;
            }
        }
        if(skipRest) {
            continue;
        }

        // Pawn, King
        x = _helpWKingPosition[0] - 1;
        y = _helpWKingPosition[1] - 1;
        if (x >= 0 && y >= 0 && (_helpBoard[x][y] == B_PAWN || _helpBoard[x][y] == B_KING)){
            if (i != *countMoves - 1){
               moveList[i] = moveList[*countMoves - 1];
            }
            --(*countMoves);
            continue;
        }

        x = _helpWKingPosition[0] + 1;
        if (x < 8 && y >= 0 && (_helpBoard[x][y] == B_PAWN || _helpBoard[x][y] == B_KING)){
            if (i != *countMoves - 1){
               moveList[i] = moveList[*countMoves - 1];
            }
            --(*countMoves);
            continue;
        }

        x = _helpWKingPosition[0] - 1;
        y = _helpWKingPosition[1];
        if (x >= 0 && _helpBoard[x][y] == B_KING){
            if (i != *countMoves - 1){
               moveList[i] = moveList[*countMoves - 1];
            }
            --(*countMoves);
            continue;
        }
        x = _helpWKingPosition[0] - 1;
        y = _helpWKingPosition[1] + 1;
        if (x >= 0 && y < 8 && _helpBoard[x][y] == B_KING){
            if (i != *countMoves - 1){
               moveList[i] = moveList[*countMoves - 1];
            }
            --(*countMoves);
            continue;
        }
        x = _helpWKingPosition[0];
        y = _helpWKingPosition[1] - 1;
        if (y >= 0 && _helpBoard[x][y] == B_KING){
            if (i != *countMoves - 1){
               moveList[i] = moveList[*countMoves - 1];
            }
            --(*countMoves);
            continue;
        }
        x = _helpWKingPosition[0];
        y = _helpWKingPosition[1] + 1;
        if (y < 8 && _helpBoard[x][y] == B_KING){
            if (i != *countMoves - 1){
               moveList[i] = moveList[*countMoves - 1];
            }
            --(*countMoves);
            continue;
        }
        x = _helpWKingPosition[0] + 1;
        y = _helpWKingPosition[1];
        if (x < 8 && _helpBoard[x][y] == B_KING){
            if (i != *countMoves - 1){
               moveList[i] = moveList[*countMoves - 1];
            }
            --(*countMoves);
            continue;
        }
        x = _helpWKingPosition[0] + 1;
        y = _helpWKingPosition[1] + 1;
        if (x < 8 && y < 8 && _helpBoard[x][y] == B_KING){
            if (i != *countMoves - 1){
               moveList[i] = moveList[*countMoves - 1];
            }
            --(*countMoves);
            continue;
        }

    }

}

void BoardState::isCheckB(Move *moveList, int *countMoves)
{
    int x, y;
    for (int i = (*countMoves)-1; i >= 0 ; --i) {
        // clone _board to _helpBoard
        for(y = 0; y < 8; ++y) {
            for(int x = 0; x < 8; ++x) {
                _helpBoard[x][y] = _board[x][y];
            }
        }
        _helpBKingPosition[0] = _bKingPosition[0];
        _helpBKingPosition[1] = _bKingPosition[1];
        modifyHelpBoard(moveList[i]);


        // Knight
        x = _helpBKingPosition[0] + 2;
        y = _helpBKingPosition[1] + 1;
        if (y >= 0 && y < 8 && x >= 0 && x < 8 && _helpBoard[x][y] == W_KNIGHT) {
            if (i != *countMoves - 1){
               moveList[i] = moveList[*countMoves - 1];
            }
            --(*countMoves);
            continue;
        }
        x = _helpBKingPosition[0] + 2;
        y = _helpBKingPosition[1] - 1;
        if (y >= 0 && y < 8 && x >= 0 && x < 8 && _helpBoard[x][y] == W_KNIGHT) {
            if (i != *countMoves - 1){
               moveList[i] = moveList[*countMoves - 1];
            }
            --(*countMoves);
            continue;
        }
        x = _helpBKingPosition[0] - 2;
        y = _helpBKingPosition[1] + 1;
        if (y < 8 && x >= 0 && _helpBoard[x][y] == W_KNIGHT) {
            if (i != *countMoves - 1){
               moveList[i] = moveList[*countMoves - 1];
            }
            --(*countMoves);
            continue;
        }
        // ---
        x = _helpBKingPosition[0] - 2;
        y = _helpBKingPosition[1] - 1;
        if (y >= 0 && x >= 0 && _helpBoard[x][y] == W_KNIGHT) {
            if (i != *countMoves - 1){
               moveList[i] = moveList[*countMoves - 1];
            }
            --(*countMoves);
            continue;
        }
        // ---
        x = _helpBKingPosition[0] + 1;
        y = _helpBKingPosition[1] + 2;
        if (y >= 0 && y < 8 && x >= 0 && x < 8 && _helpBoard[x][y] == W_KNIGHT) {
            if (i != *countMoves - 1){
               moveList[i] = moveList[*countMoves - 1];
            }
            --(*countMoves);
            continue;
        }
        x = _helpBKingPosition[0] + 1;
        y = _helpBKingPosition[1] - 2;
        if (y >= 0 && y < 8 && x >= 0 && x < 8 && _helpBoard[x][y] == W_KNIGHT) {
            if (i != *countMoves - 1){
               moveList[i] = moveList[*countMoves - 1];
            }
            --(*countMoves);
            continue;
        }
        x = _helpBKingPosition[0] - 1;
        y = _helpBKingPosition[1] + 2;
        if (y >= 0 && y < 8 && x >= 0 && x < 8 && _helpBoard[x][y] == W_KNIGHT) {
            if (i != *countMoves - 1){
               moveList[i] = moveList[*countMoves - 1];
            }
            --(*countMoves);
            continue;
        }
        x = _helpBKingPosition[0] - 1;
        y = _helpBKingPosition[1] - 2;
        if (y >= 0 && y < 8 && x >= 0 && x < 8 && _helpBoard[x][y] == W_KNIGHT) {
            if (i != *countMoves - 1){
               moveList[i] = moveList[*countMoves - 1];
            }
            --(*countMoves);
            continue;
        }

        //Queen, Bishop & Rook
        bool skipRest = false;

        // East
        x = _helpBKingPosition[0] + 1;
        y = _helpBKingPosition[1];
        while (x < 8) {
            if (_helpBoard[x][y] == EMPTY) {
                ++x;
            } else if (_helpBoard[x][y] == W_QUEEN || _helpBoard[x][y] == W_ROOK) {
                if (i != *countMoves - 1){
                   moveList[i] = moveList[*countMoves - 1];
                }
                --(*countMoves);
                skipRest = true;
                break;
            } else {
                break;
            }
        }
        if(skipRest) {
            continue;
        }

        // West
        x = _helpBKingPosition[0] - 1;
        y = _helpBKingPosition[1];
        while (x >= 0) {
            if (_helpBoard[x][y] == EMPTY) {
                --x;
            } else if (_helpBoard[x][y] == W_QUEEN || _helpBoard[x][y] == W_ROOK) {
                if (i != *countMoves - 1){
                   moveList[i] = moveList[*countMoves - 1];
                }
                --(*countMoves);
                skipRest = true;
                break;
            } else {
                break;
            }
        }
        if(skipRest) {
            continue;
        }

        // South
        x = _helpBKingPosition[0];
        y = _helpBKingPosition[1] + 1;
        while (y < 8) {
            if (_helpBoard[x][y] == EMPTY) {
                ++y;
            } else if (_helpBoard[x][y] == W_QUEEN || _helpBoard[x][y] == W_ROOK) {
                if (i != *countMoves - 1){
                   moveList[i] = moveList[*countMoves - 1];
                }
                --(*countMoves);
                skipRest = true;
                break;
            } else {
                break;
            }
        }
        if(skipRest) {
            continue;
        }

        // North
        x = _helpBKingPosition[0];
        y = _helpBKingPosition[1] - 1;
        while (y >= 0) {
            if (_helpBoard[x][y] == EMPTY) {
                --y;
            } else if (_helpBoard[x][y] == W_QUEEN || _helpBoard[x][y] == W_ROOK) {
                if (i != *countMoves - 1){
                   moveList[i] = moveList[*countMoves - 1];
                }
                --(*countMoves);
                skipRest = true;
                break;
            } else {
                break;
            }
        }
        if(skipRest) {
            continue;
        }

        // North-East
        x = _helpBKingPosition[0] + 1;
        y = _helpBKingPosition[1] - 1;
        while (x < 8 && y >= 0) {
            if (_helpBoard[x][y] == EMPTY) {
                ++x;
                --y;
            } else if (_helpBoard[x][y] == W_QUEEN || _helpBoard[x][y] == W_BISHOP) {
                if (i != *countMoves - 1){
                   moveList[i] = moveList[*countMoves - 1];
                }
                --(*countMoves);
                skipRest = true;
                break;
            } else {
                break;
            }
        }
        if(skipRest) {
            continue;
        }

        // South-East
        x = _helpBKingPosition[0] + 1;
        y = _helpBKingPosition[1] + 1;
        while (x < 8 && y < 8) {
            if (_helpBoard[x][y] == EMPTY) {
                ++x;
                ++y;
            } else if (_helpBoard[x][y] == W_QUEEN || _helpBoard[x][y] == W_BISHOP) {
                if (i != *countMoves - 1){
                   moveList[i] = moveList[*countMoves - 1];
                }
                --(*countMoves);
                skipRest = true;
                break;
            } else {
                break;
            }
        }
        if(skipRest) {
            continue;
        }

        // North-West
        x = _helpBKingPosition[0] - 1;
        y = _helpBKingPosition[1] - 1;
        while (x >= 0 && y >= 0) {
            if (_helpBoard[x][y] == EMPTY) {
                --x;
                --y;
            } else if (_helpBoard[x][y] == W_QUEEN || _helpBoard[x][y] == W_BISHOP) {
                if (i != *countMoves - 1){
                   moveList[i] = moveList[*countMoves - 1];
                }
                --(*countMoves);
                skipRest = true;
                break;
            } else {
                break;
            }
        }
        if(skipRest) {
            continue;
        }

        // South-West
        x = _helpBKingPosition[0] - 1;
        y = _helpBKingPosition[1] + 1;
        while (x >= 0 && y < 8) {
            if (_helpBoard[x][y] == EMPTY) {
                --x;
                ++y;
            } else if (_helpBoard[x][y] == W_QUEEN || _helpBoard[x][y] == W_BISHOP) {
                if (i != *countMoves - 1){
                   moveList[i] = moveList[*countMoves - 1];
                }
                --(*countMoves);
                skipRest = true;
                break;
            } else {
                break;
            }
        }
        if(skipRest) {
            continue;
        }

        // Pawn, King
        x = _helpBKingPosition[0] - 1;
        y = _helpBKingPosition[1] + 1;
        if (x >= 0 && y < 8 && (_helpBoard[x][y] == W_PAWN || _helpBoard[x][y] == W_KING)){
            if (i != *countMoves - 1){
               moveList[i] = moveList[*countMoves - 1];
            }
            --(*countMoves);
            continue;
        }

        x = _helpBKingPosition[0] + 1;
        if (x < 8 && y < 8 && (_helpBoard[x][y] == W_PAWN || _helpBoard[x][y] == W_KING)){
            if (i != *countMoves - 1){
               moveList[i] = moveList[*countMoves - 1];
            }
            --(*countMoves);
            continue;
        }

        x = _helpBKingPosition[0] - 1;
        y = _helpBKingPosition[1];
        if (x >= 0 && _helpBoard[x][y] == W_KING){
            if (i != *countMoves - 1){
               moveList[i] = moveList[*countMoves - 1];
            }
            --(*countMoves);
            continue;
        }
        x = _helpBKingPosition[0] - 1;
        y = _helpBKingPosition[1] - 1;
        if (x >= 0 && y >= 0 && _helpBoard[x][y] == W_KING){
            if (i != *countMoves - 1){
               moveList[i] = moveList[*countMoves - 1];
            }
            --(*countMoves);
            continue;
        }
        x = _helpBKingPosition[0];
        y = _helpBKingPosition[1] - 1;
        if (y >= 0 && _helpBoard[x][y] == W_KING){
            if (i != *countMoves - 1){
               moveList[i] = moveList[*countMoves - 1];
            }
            --(*countMoves);
            continue;
        }
        x = _helpBKingPosition[0];
        y = _helpBKingPosition[1] + 1;
        if (y < 8 && _helpBoard[x][y] == W_KING){
            if (i != *countMoves - 1){
               moveList[i] = moveList[*countMoves - 1];
            }
            --(*countMoves);
            continue;
        }
        x = _helpBKingPosition[0] + 1;
        y = _helpBKingPosition[1];
        if (x < 8 && _helpBoard[x][y] == W_KING){
            if (i != *countMoves - 1){
               moveList[i] = moveList[*countMoves - 1];
            }
            --(*countMoves);
            continue;
        }
        x = _helpBKingPosition[0] + 1;
        y = _helpBKingPosition[1] - 1;
        if (x < 8 && y >= 0 && _helpBoard[x][y] == W_KING){
            if (i != *countMoves - 1){
               moveList[i] = moveList[*countMoves - 1];
            }
            --(*countMoves);
            continue;
        }

    }
}

void BoardState::genLegalMovesWKing(Move *moveList, int xOrg, int yOrg, int *countMoves)
{
    int x, y;
    x = xOrg + 1; // east
    if (x < 8){
        if (!isWhitePiece(x, yOrg)) {
            moveList[*countMoves] = Move(xOrg,yOrg,x,yOrg);
            ++(*countMoves);
        }
    }

    x = xOrg - 1; // west
    if (x >= 0){
        if (!isWhitePiece(x, yOrg)) {
            moveList[*countMoves] = Move(xOrg,yOrg,x,yOrg);
            ++(*countMoves);
        }
    }

    y = yOrg + 1; // south
    if (y < 8){
        if (!isWhitePiece(xOrg, y)) {
            moveList[*countMoves] = Move(xOrg,yOrg,xOrg,y);
            ++(*countMoves);
        }
    }

    y = yOrg - 1; // north
    if (y >= 0){
        if (!isWhitePiece(xOrg, y)) {
            moveList[*countMoves] = Move(xOrg,yOrg,xOrg,y);
            ++(*countMoves);
        }
    }

    y = yOrg + 1; // south
    x = xOrg + 1; // east
    if ((x < 8) && (y < 8)){
        if (!isWhitePiece(x, y)) {
            moveList[*countMoves] = Move(xOrg,yOrg,x,y);
            ++(*countMoves);
        }
    }

    y = yOrg - 1; // south
    x = xOrg - 1; // west
    if ((x >= 0) && (y >= 0)){
        if (!isWhitePiece(x, y)) {
            moveList[*countMoves] = Move(xOrg,yOrg,x,y);
            ++(*countMoves);
        }
    }

    y = yOrg + 1; // north
    x = xOrg - 1; // west
    if ((x >= 0) && (y < 8)){
        if (!isWhitePiece(x, y)) {
            moveList[*countMoves] = Move(xOrg,yOrg,x,y);
            ++(*countMoves);
        }
    }

    y = yOrg - 1; // north
    x = xOrg + 1; // east
    if ((x < 8) && (y >= 0)){
        if (!isWhitePiece(x, y)) {
            moveList[*countMoves] = Move(xOrg,yOrg,x,y);
            ++(*countMoves);
        }
    }

    // CastleLong (castle to left)
    if (_wCastleLongAllowed &&
        (_board[1][7] == EMPTY) &&
        (_board[2][7] == EMPTY) &&
        (_board[3][7] == EMPTY)){
        // Check that the king or the square he jumps over are not threathened
        // The square he lands in are checked in the genlegalmoves as normal
        int helpCountMoves = 2;
        Move helpList[2];
        helpList[0] = Move(4,7,4,7);
        helpList[1] = Move(4,7,3,7);
        isCheckW(helpList, &helpCountMoves);
        if (helpCountMoves == 2){
            moveList[*countMoves] = Move(4,7,2,7,CASTLELONG);
            ++(*countMoves);
        }
    }

    // CastleShort (castle to right)
    if (_wCastleShortAllowed &&
        (_board[5][7] == EMPTY) &&
        (_board[6][7] == EMPTY)){
        // Check that the king or the square he jumps over are not threathened
        // The square he lands in are checked in the genlegalmoves as normal
        int helpCountMoves = 2;
        Move helpList[2];
        helpList[0] = Move(4,7,4,7);
        helpList[1] = Move(4,7,5,7);
        isCheckW(helpList, &helpCountMoves);
        if (helpCountMoves == 2){
            moveList[*countMoves] = Move(4,7,6,7,CASTLESHORT);
            ++(*countMoves);
        }
    }
}

void BoardState::genLegalMovesBKing(Move *moveList, int xOrg, int yOrg, int *countMoves)
{
    int x, y;
    x = xOrg + 1; // east
    if (x < 8){
        if (!isBlackPiece(x, yOrg)) {
            moveList[*countMoves] = Move(xOrg,yOrg,x,yOrg);
            ++(*countMoves);
        }
    }

    x = xOrg - 1; // west
    if (x >= 0){
        if (!isBlackPiece(x, yOrg)) {
            moveList[*countMoves] = Move(xOrg,yOrg,x,yOrg);
            ++(*countMoves);
        }
    }

    y = yOrg + 1; // south
    if (y < 8){
        if (!isBlackPiece(xOrg, y)) {
            moveList[*countMoves] = Move(xOrg,yOrg,xOrg,y);
            ++(*countMoves);
        }
    }

    y = yOrg - 1; // north
    if (y >= 0){
        if (!isBlackPiece(xOrg, y)) {
            moveList[*countMoves] = Move(xOrg,yOrg,xOrg,y);
            ++(*countMoves);
        }
    }

    y = yOrg + 1; // south
    x = xOrg + 1; // east
    if ((x < 8) && (y < 8)){
        if (!isBlackPiece(x, y)) {
            moveList[*countMoves] = Move(xOrg,yOrg,x,y);
            ++(*countMoves);
        }
    }

    y = yOrg - 1; // south
    x = xOrg - 1; // west
    if ((x >= 0) && (y >= 0)){
        if (!isBlackPiece(x, y)) {
            moveList[*countMoves] = Move(xOrg,yOrg,x,y);
            ++(*countMoves);
        }
    }

    y = yOrg + 1; // north
    x = xOrg - 1; // west
    if ((x >= 0) && (y < 8)){
        if (!isBlackPiece(x, y)) {
            moveList[*countMoves] = Move(xOrg,yOrg,x,y);
            ++(*countMoves);
        }
    }

    y = yOrg - 1; // north
    x = xOrg + 1; // east
    if ((x < 8) && (y >= 0)){
        if (!isBlackPiece(x, y)) {
            moveList[*countMoves] = Move(xOrg,yOrg,x,y);
            ++(*countMoves);
        }
    }

    // CastleLong (castle to left)
    if (_bCastleLongAllowed &&
        (_board[1][0] == EMPTY) &&
        (_board[2][0] == EMPTY) &&
        (_board[3][0] == EMPTY)){
        // Check that the king or the square he jumps over are not threathened
        // The square he lands in are checked in the genlegalmoves as normal
        int helpCountMoves = 2;
        Move helpList[2];
        helpList[0] = Move(4,0,4,0);
        helpList[1] = Move(4,0,3,0);
        isCheckB(helpList, &helpCountMoves);
        if (helpCountMoves == 2){
            moveList[*countMoves] = Move(4,0,2,0,CASTLELONG);
            ++(*countMoves);
        }
    }

    // CastleShort (castle to right)
    if (_bCastleShortAllowed &&
        (_board[5][0] == EMPTY) &&
        (_board[6][0] == EMPTY)){
        // Check that the king or the square he jumps over are not threathened
        // The square he lands in are checked in the genlegalmoves as normal
        int helpCountMoves = 2;
        Move helpList[2];
        helpList[0] = Move(4,0,4,0);
        helpList[1] = Move(4,0,5,0);
        isCheckB(helpList, &helpCountMoves);
        if (helpCountMoves == 2){
            moveList[*countMoves] = Move(4,0,6,0,CASTLESHORT);
            ++(*countMoves);
        }
    }
}

void BoardState::genLegalMovesWKnight(Move *moveList, int xOrg, int yOrg, int *countMoves)
{
    int x = xOrg;
    int y = yOrg;
    // Check north
    y = yOrg -2;
    if(y >= 0) { // Enough room to move 2 north
        x = xOrg -1;
        if(x >= 0) { // Enough room to move 2 north 1 west
            if(!isWhitePiece(x, y)) { // Legal move
                moveList[*countMoves] = Move(xOrg,yOrg, x, y);
                ++(*countMoves);
            }
        }
        x = xOrg +1;
        if(xOrg +1 <= 7) { // Enough room to move 2 north 1 east
            if(!isWhitePiece(x, y)) { // Legal move
                moveList[*countMoves] = Move(xOrg,yOrg, x, y);
                ++(*countMoves);
            }
        }
    }
    // Check South
    y = yOrg +2;
    if(y <= 7) { // Enough room to move 2 south
        x = xOrg -1;
        if(x >= 0) { // Enough room to move 2 south 1 west
            if(!isWhitePiece(x, y)) { // Legal move
                moveList[*countMoves] = Move(xOrg,yOrg, x, y);
                ++(*countMoves);
            }
        }
        x = xOrg +1;
        if(x <= 7) { // Enough room to move 2 south 1 east
            if(!isWhitePiece(x, y)) { // Legal move
                moveList[*countMoves] = Move(xOrg,yOrg, x, y);
                ++(*countMoves);
            }
        }
    }
    // Check West
    x = xOrg -2;
    if(x >= 0) { // Enough room to move 2 west
        y = yOrg -1;
        if(y >= 0) { // Enough room to move 2 west 1 north
            if(!isWhitePiece(x, y)) { // Legal move
                moveList[*countMoves] = Move(xOrg,yOrg, x, y);
                ++(*countMoves);
            }
        }
        y = yOrg +1;
        if(y <= 7) { // Enough room to move 2 west 1 south
            if(!isWhitePiece(x, y)) { // Legal move
                moveList[*countMoves] = Move(xOrg,yOrg, x, y);
                ++(*countMoves);
            }
        }
    }
    // Check East
    x = xOrg +2;
    if(x <= 7) { // Enough room to move 2 east
        y = yOrg -1;
        if(y >= 0) { // Enough room to move 2 east 1 north
            x = xOrg +2;
            if(!isWhitePiece(x, y)) { // Legal move
                moveList[*countMoves] = Move(xOrg,yOrg, x, y);
                ++(*countMoves);
            }
        }
        y = yOrg +1;
        if(y <= 7) { // Enough room to move 2 east 1 south
            if(!isWhitePiece(x, y)) { // Legal move
                moveList[*countMoves] = Move(xOrg,yOrg, x, y);
                ++(*countMoves);
            }
        }
    }
}

void BoardState::genLegalMovesBKnight(Move *moveList, int xOrg, int yOrg, int *countMoves)
{
    int x = xOrg;
    int y = yOrg;
    // Check north
    y = yOrg -2;
    if(y >= 0) { // Enough room to move 2 north
        x = xOrg -1;
        if(x >= 0) { // Enough room to move 2 north 1 west
            if(!isBlackPiece(x, y)) { // Legal move
                moveList[*countMoves] = Move(xOrg,yOrg, x, y);
                ++(*countMoves);
            }
        }
        x = xOrg +1;
        if(xOrg +1 <= 7) { // Enough room to move 2 north 1 east
            if(!isBlackPiece(x, y)) { // Legal move
                moveList[*countMoves] = Move(xOrg,yOrg, x, y);
                ++(*countMoves);
            }
        }
    }
    // Check South
    y = yOrg +2;
    if(y <= 7) { // Enough room to move 2 north
        x = xOrg -1;
        if(x >= 0) { // Enough room to move 2 south 1 west
            if(!isBlackPiece(x, y)) { // Legal move
                moveList[*countMoves] = Move(xOrg,yOrg, x, y);
                ++(*countMoves);
            }
        }
        x = xOrg +1;
        if(x <= 7) { // Enough room to move 2 south 1 east
            if(!isBlackPiece(x, y)) { // Legal move
                moveList[*countMoves] = Move(xOrg,yOrg, x, y);
                ++(*countMoves);
            }
        }
    }
    // Check West
    x = xOrg -2;
    if(x >= 0) { // Enough room to move 2 west
        y = yOrg -1;
        if(y >= 0) { // Enough room to move 2 west 1 north
            if(!isBlackPiece(x, y)) { // Legal move
                moveList[*countMoves] = Move(xOrg,yOrg, x, y);
                ++(*countMoves);
            }
        }
        y = yOrg +1;
        if(y <= 7) { // Enough room to move 2 west 1 south
            if(!isBlackPiece(x, y)) { // Legal move
                moveList[*countMoves] = Move(xOrg,yOrg, x, y);
                ++(*countMoves);
            }
        }
    }
    // Check East
    x = xOrg +2;
    if(x <= 7) { // Enough room to move 2 east
        y = yOrg -1;
        if(y >= 0) { // Enough room to move 2 east 1 north
            x = xOrg +2;
            if(!isBlackPiece(x, y)) { // Legal move
                moveList[*countMoves] = Move(xOrg,yOrg, x, y);
                ++(*countMoves);
            }
        }
        y = yOrg +1;
        if(y <= 7) { // Enough room to move 2 east 1 south
            if(!isBlackPiece(x, y)) { // Legal move
                moveList[*countMoves] = Move(xOrg,yOrg, x, y);
                ++(*countMoves);
            }
        }
    }
}

void BoardState::genLegalMovesWQueen(Move *moveList, int xOrg, int yOrg, int *countMoves)
{
    genLegalMovesWRook(moveList, xOrg, yOrg, countMoves);
    genLegalMovesWBishop(moveList, xOrg, yOrg, countMoves);
}

void BoardState::genLegalMovesBQueen(Move *moveList, int xOrg, int yOrg, int *countMoves)
{
    genLegalMovesBRook(moveList, xOrg, yOrg, countMoves);
    genLegalMovesBBishop(moveList, xOrg, yOrg, countMoves);
}

void BoardState::genLegalMovesWRook(Move *moveList, int xOrg, int yOrg, int *countMoves)
{
    int x = xOrg;
    while (x < 7) { //check all squares to right
        ++x;
        if (_board[x][yOrg] == EMPTY){
            moveList[*countMoves] = Move(xOrg,yOrg,x,yOrg);
            ++(*countMoves);
        } else if (!isWhitePiece(x, yOrg)) {
            moveList[*countMoves] = Move(xOrg,yOrg,x,yOrg);
            ++(*countMoves);
            break;
        } else { // it is own piece
            break;
        }
    }

    x = xOrg;
    while (x > 0) { //check all squares to left
        --x;
        if (_board[x][yOrg] == EMPTY){
            moveList[*countMoves] = Move(xOrg,yOrg,x,yOrg);
            ++(*countMoves);
        } else if (!isWhitePiece(x, yOrg)) {
            moveList[*countMoves] = Move(xOrg,yOrg,x,yOrg);
            ++(*countMoves);
            break;
        } else { // it is own piece
            break;
        }
    }

    int y = yOrg;
    while (y > 0) { //check all squares to up
        --y;
        if (_board[xOrg][y] == EMPTY){
            moveList[*countMoves] = Move(xOrg,yOrg,xOrg,y);
            ++(*countMoves);
        } else if (!isWhitePiece(xOrg, y)) {
            moveList[*countMoves] = Move(xOrg,yOrg,xOrg,y);
            ++(*countMoves);
            break;
        } else { // own piece
            break;
        }
    }

    y = yOrg;
    while (y < 7) { //check all squares to down
        ++y;
        if (_board[xOrg][y] == EMPTY){
            moveList[*countMoves] = Move(xOrg,yOrg,xOrg,y);
            ++(*countMoves);
        } else if (!isWhitePiece(xOrg, y)) {
            moveList[*countMoves] = Move(xOrg,yOrg,xOrg,y);
            ++(*countMoves);
            break;
        } else { // own piece
            break;
        }
    }
}

void BoardState::genLegalMovesBRook(Move *moveList, int xOrg, int yOrg, int *countMoves)
{
    int x = xOrg;
    while (x < 7) { //check all squares to right
        ++x;
        if (_board[x][yOrg] == EMPTY){
            moveList[*countMoves] = Move(xOrg,yOrg,x,yOrg);
            ++(*countMoves);
        } else if (!isBlackPiece(x, yOrg)) {
            moveList[*countMoves] = Move(xOrg,yOrg,x,yOrg);
            ++(*countMoves);
            break;
        } else { // own piece
            break;
        }
    }

    x = xOrg;
    while (x > 0) { //check all squares to left
        --x;
        if (_board[x][yOrg] == EMPTY){
            moveList[*countMoves] = Move(xOrg,yOrg,x,yOrg);
            ++(*countMoves);
        } else if (!isBlackPiece(x, yOrg)) {
            moveList[*countMoves] = Move(xOrg,yOrg,x,yOrg);
            ++(*countMoves);
            break;
        } else { // own piece
            break;
        }
    }

    int y = yOrg;
    while (y > 0) { //check all squares to up
        --y;
        if (_board[xOrg][y] == EMPTY){
            moveList[*countMoves] = Move(xOrg,yOrg,xOrg,y);
            ++(*countMoves);
        } else if (!isBlackPiece(xOrg, y)) {
            moveList[*countMoves] = Move(xOrg,yOrg,xOrg,y);
            ++(*countMoves);
            break;
        } else { // own piece
            break;
        }
    }

    y = yOrg;
    while (y < 7) { //check all squares to down
        ++y;
        if (_board[xOrg][y] == EMPTY){
            moveList[*countMoves] = Move(xOrg,yOrg,xOrg,y);
            ++(*countMoves);
        } else if (!isBlackPiece(xOrg, y)) {
            moveList[*countMoves] = Move(xOrg,yOrg,xOrg,y);
            ++(*countMoves);
            break;
        } else { // own piece
            break;
        }
    }
}

void BoardState::genLegalMovesWBishop(Move *moveList, int xOrg, int yOrg, int *countMoves)
{
    int x = xOrg;
    int y = yOrg;
    while(x > 0 && y > 0){ //left, up
        --x;
        --y;
        if(_board[x][y] == EMPTY){
            moveList[*countMoves] = Move(xOrg, yOrg, x, y);
            ++(*countMoves);
        } else if (!isWhitePiece(x, y)) { //you can eat it
            moveList[*countMoves] = Move(xOrg, yOrg, x, y);
            ++(*countMoves);
            break;
        } else { //own piece
            break;
        }
    }

    x = xOrg;
    y = yOrg;
    while(x < 7 && y > 0){ //right, up
        ++x;
        --y;
        if(_board[x][y] == EMPTY){
            moveList[*countMoves] = Move(xOrg, yOrg, x, y);
            ++(*countMoves);
        } else if (!isWhitePiece(x, y)) { //you can eat it
            moveList[*countMoves] = Move(xOrg, yOrg, x, y);
            ++(*countMoves);
            break;
        } else { //own piece
            break;
        }
    }
    x = xOrg;
    y = yOrg;
    while(x > 0 && y < 7){ //left, down
        --x;
        ++y;
        if(_board[x][y] == EMPTY){
            moveList[*countMoves] = Move(xOrg, yOrg, x, y);
            ++(*countMoves);
        } else if (!isWhitePiece(x, y)) { //you can eat it
            moveList[*countMoves] = Move(xOrg, yOrg, x, y);
            ++(*countMoves);
            break;
        } else { //own piece
            break;
        }
    }
    x = xOrg;
    y = yOrg;
    while(x < 7 && y < 7){ //right, down
        ++x;
        ++y;
        if(_board[x][y] == EMPTY){
            moveList[*countMoves] = Move(xOrg, yOrg, x, y);
            ++(*countMoves);
        } else if (!isWhitePiece(x, y)) { //you can eat it
            moveList[*countMoves] = Move(xOrg, yOrg, x, y);
            ++(*countMoves);
            break;
        } else { //own piece
            break;
        }
    }


}

void BoardState::genLegalMovesBBishop(Move *moveList, int xOrg, int yOrg, int *countMoves)
{
    int x = xOrg;
    int y = yOrg;
    while(x > 0 && y > 0){ //left, up
        --x;
        --y;
        if(_board[x][y] == EMPTY){
            moveList[*countMoves] = Move(xOrg, yOrg, x, y);
            ++(*countMoves);
        } else if (!isBlackPiece(x, y)) { //you can eat it
            moveList[*countMoves] = Move(xOrg, yOrg, x, y);
            ++(*countMoves);
            break;
        } else { //own piece
            break;
        }
    }

    x = xOrg;
    y = yOrg;
    while(x < 7 && y > 0){ //right, up
        ++x;
        --y;
        if(_board[x][y] == EMPTY){
            moveList[*countMoves] = Move(xOrg, yOrg, x, y);
            ++(*countMoves);
        } else if (!isBlackPiece(x, y)) { //you can eat it
            moveList[*countMoves] = Move(xOrg, yOrg, x, y);
            ++(*countMoves);
            break;
        } else { //own piece
            break;
        }
    }
    x = xOrg;
    y = yOrg;
    while(x > 0 && y < 7){ //left, down
        --x;
        ++y;
        if(_board[x][y] == EMPTY){
            moveList[*countMoves] = Move(xOrg, yOrg, x, y);
            ++(*countMoves);
        } else if (!isBlackPiece(x, y)) { //you can eat it
            moveList[*countMoves] = Move(xOrg, yOrg, x, y);
            ++(*countMoves);
            break;
        } else { //own piece
            break;
        }
    }
    x = xOrg;
    y = yOrg;
    while(x < 7 && y < 7){ //right, down
        ++x;
        ++y;
        if(_board[x][y] == EMPTY){
            moveList[*countMoves] = Move(xOrg, yOrg, x, y);
            ++(*countMoves);
        } else if (!isBlackPiece(x, y)) { //you can eat it
            moveList[*countMoves] = Move(xOrg, yOrg, x, y);
            ++(*countMoves);
            break;
        } else { //own piece
            break;
        }
    }
}

void BoardState::genLegalMovesWPawn(Move *moveList, int xOrg, int yOrg, int *countMoves)
{
    int x = xOrg;
    int y = yOrg;

    y = yOrg - 1; // Regular move
    if(_board[x][y] == EMPTY) {
        if(y != 0) {
            moveList[*countMoves] = Move(xOrg,yOrg,x,y);
            ++(*countMoves);
        }

        if(yOrg == 6) {
            y = yOrg -2; // First move can be 2
            if(_board[x][y] == EMPTY) {
                moveList[*countMoves] = Move(xOrg,yOrg,x,y);
                ++(*countMoves);
            }
        } else if(y == 0) { // At north end of the column -> Promote
            moveList[*countMoves] = Move(xOrg, yOrg, x, y, QUEEN);
            ++(*countMoves);
            moveList[*countMoves] = Move(xOrg, yOrg, x, y, BISHOP);
            ++(*countMoves);
            moveList[*countMoves] = Move(xOrg, yOrg, x, y, KNIGHT);
            ++(*countMoves);
            moveList[*countMoves] = Move(xOrg, yOrg, x, y, ROOK);
            ++(*countMoves);
        }
    }

    y = yOrg -1; // Capturing
    x = xOrg -1; // Capturing west
    if(x >= 0 && isBlackPiece(x, y)) {
        if(y == 0) { // At north end of the column -> Promote
            moveList[*countMoves] = Move(xOrg, yOrg, x, y, QUEEN);
            ++(*countMoves);
            moveList[*countMoves] = Move(xOrg, yOrg, x, y, BISHOP);
            ++(*countMoves);
            moveList[*countMoves] = Move(xOrg, yOrg, x, y, KNIGHT);
            ++(*countMoves);
            moveList[*countMoves] = Move(xOrg, yOrg, x, y, ROOK);
            ++(*countMoves);
        } else {
            moveList[*countMoves] = Move(xOrg,yOrg,x,y);
            ++(*countMoves);
        }
    }
    x = xOrg +1; // Capturing east
    if(x < 8 && isBlackPiece(x, y)) {
        if(y == 0) { // At north end of the column -> Promote
            moveList[*countMoves] = Move(xOrg, yOrg, x, y, QUEEN);
            ++(*countMoves);
            moveList[*countMoves] = Move(xOrg, yOrg, x, y, BISHOP);
            ++(*countMoves);
            moveList[*countMoves] = Move(xOrg, yOrg, x, y, KNIGHT);
            ++(*countMoves);
            moveList[*countMoves] = Move(xOrg, yOrg, x, y, ROOK);
            ++(*countMoves);
        } else {
            moveList[*countMoves] = Move(xOrg,yOrg,x,y);
            ++(*countMoves);
        }
    }

    if(yOrg == 3) { // en passat
        if(_bPawnAdvancedTwo == xOrg -1 && xOrg != 0) {
            moveList[*countMoves] = Move(xOrg, yOrg, _bPawnAdvancedTwo, y, PASSAT);
            ++(*countMoves);
        } else if(_bPawnAdvancedTwo == xOrg +1 && xOrg != 7) {
            moveList[*countMoves] = Move(xOrg, yOrg, _bPawnAdvancedTwo, y, PASSAT);
            ++(*countMoves);
        }
    }
}

void BoardState::genLegalMovesBPawn(Move *moveList, int xOrg, int yOrg, int *countMoves)
{
    int x = xOrg;
    int y = yOrg;

    y = yOrg + 1; // Regular move
    if(_board[x][y] == EMPTY) {
        if(y != 7) {
            moveList[*countMoves] = Move(xOrg,yOrg,x,y);
            ++(*countMoves);
        }

        if(yOrg == 1) {
            y = yOrg +2; // First move can be 2
            if(_board[x][y] == EMPTY) {
                moveList[*countMoves] = Move(xOrg,yOrg,x,y);
                ++(*countMoves);
            }
        } else if(y == 7) { // At north end of the column -> Promote
            moveList[*countMoves] = Move(xOrg, yOrg, x, y, QUEEN);
            ++(*countMoves);
            moveList[*countMoves] = Move(xOrg, yOrg, x, y, BISHOP);
            ++(*countMoves);
            moveList[*countMoves] = Move(xOrg, yOrg, x, y, KNIGHT);
            ++(*countMoves);
            moveList[*countMoves] = Move(xOrg, yOrg, x, y, ROOK);
            ++(*countMoves);
        }
    }

    y = yOrg +1; // Capturing
    x = xOrg -1; // Capturing west
    if(x >= 0 && isWhitePiece(x, y)) {
        if(y == 7) { // At north end of the column -> Promote
            moveList[*countMoves] = Move(xOrg, yOrg, x, y, QUEEN);
            ++(*countMoves);
            moveList[*countMoves] = Move(xOrg, yOrg, x, y, BISHOP);
            ++(*countMoves);
            moveList[*countMoves] = Move(xOrg, yOrg, x, y, KNIGHT);
            ++(*countMoves);
            moveList[*countMoves] = Move(xOrg, yOrg, x, y, ROOK);
            ++(*countMoves);
        } else {
            moveList[*countMoves] = Move(xOrg,yOrg,x,y);
            ++(*countMoves);
        }
    }
    x = xOrg +1; // Capturing east
    if(x < 8 && isWhitePiece(x, y)) {
        if(y == 7) { // At north end of the column -> Promote
            moveList[*countMoves] = Move(xOrg, yOrg, x, y, QUEEN);
            ++(*countMoves);
            moveList[*countMoves] = Move(xOrg, yOrg, x, y, BISHOP);
            ++(*countMoves);
            moveList[*countMoves] = Move(xOrg, yOrg, x, y, KNIGHT);
            ++(*countMoves);
            moveList[*countMoves] = Move(xOrg, yOrg, x, y, ROOK);
            ++(*countMoves);
        } else {
            moveList[*countMoves] = Move(xOrg,yOrg,x,y);
            ++(*countMoves);
        }
    }

    if(yOrg == 4) { // en passat
        if(_wPawnAdvancedTwo == xOrg -1 && xOrg != 0) {
            moveList[*countMoves] = Move(xOrg, yOrg, _wPawnAdvancedTwo, y, PASSAT);
            ++(*countMoves);
        } else if(_wPawnAdvancedTwo == xOrg +1 && xOrg != 7) {
            moveList[*countMoves] = Move(xOrg, yOrg, _wPawnAdvancedTwo, y, PASSAT);
            ++(*countMoves);
        }
    }
}

bool BoardState::isBlackPiece(int x, int y){
    if ((_board[x][y] == B_PAWN)  ||
        (_board[x][y] == B_ROOK)  ||
        (_board[x][y] == B_KNIGHT)||
        (_board[x][y] == B_BISHOP)||
        (_board[x][y] == B_QUEEN) ||
        (_board[x][y] == B_KING)) {
        return true;
    } else {
        return false;
    }
}

bool BoardState::isWhitePiece(int x, int y){
    if ((_board[x][y] == W_PAWN)  ||
        (_board[x][y] == W_ROOK)  ||
        (_board[x][y] == W_KNIGHT)||
        (_board[x][y] == W_BISHOP)||
        (_board[x][y] == W_QUEEN) ||
        (_board[x][y] == W_KING)) {
        return true;
    } else {
        return false;
    }
}

BoardState BoardState::clone(){
    BoardState newState = BoardState();
    for (int y=0; y<8; ++y){
        for (int x=0; x<8; ++x){
            newState._board[x][y] = _board[x][y];
        }
    }
	newState._turn = _turn;
    newState._wPawnAdvancedTwo = _wPawnAdvancedTwo;
    newState._bPawnAdvancedTwo = _bPawnAdvancedTwo;
    newState._wKingPosition[0] = _wKingPosition[0];
    newState._wKingPosition[1] = _wKingPosition[1];
    newState._bKingPosition[0] = _bKingPosition[0];
    newState._bKingPosition[1] = _bKingPosition[1];
	newState._wCastleShortAllowed = _wCastleShortAllowed;
	newState._wCastleLongAllowed = _wCastleLongAllowed;
	newState._bCastleShortAllowed = _bCastleShortAllowed;
	newState._bCastleLongAllowed = _bCastleLongAllowed;
	return newState;
}

bool BoardState::acceptDrawAs(int playerColor){
    int score = evaluate();
    if ((playerColor == WHITE && score < -180) ||
        (playerColor == BLACK && score > 180)){
        return true;
    } else {
        return false;
    }
}

Move BoardState::genBestMove(int depth){
    Move moveList[256];
    int countMoves = genLegalMoves(moveList);
    double values[countMoves];
    double largestValue = -1001, smallestValue = 1001;
    int lvIndex=0, svIndex=0;

    for (int i = 0 ; i < countMoves ; ++i){
        BoardState helpState = clone();
        helpState.execMove(moveList[i]);
        if (_turn == BLACK){
            values[i] = alphaBetaMax(-1000, 1000, depth, &helpState);
        } else { // white's turn
            values[i] = alphaBetaMin(-1000, 1000, depth, &helpState);
        }

        if (values[i] < smallestValue){
            smallestValue = values[i];
            svIndex = i;
        }
        if (values[i] > largestValue){
            largestValue = values[i];
            lvIndex = i;
        }
    }

    int highestValues[countMoves];
    int highestValuesLength = 0;
    int smallestValues[countMoves];
    int smallestValuesLength = 0;
    for(int i = 0; i < countMoves; i++) {
        if(values[i] == largestValue) {
            highestValues[highestValuesLength] = i;
            highestValuesLength++;
        }
        if ( values[i] == smallestValue) {
            smallestValues[smallestValuesLength] = i;
            smallestValuesLength++;
        }
    }

    srand ( time(NULL) );

    if (_turn == WHITE){
        return moveList[highestValues[rand()%highestValuesLength]];
    } else { // white's turn
        return moveList[smallestValues[rand()%smallestValuesLength]];
    }
}

double BoardState::alphaBetaMax(int alpha, int beta, int depth, BoardState *state){
    if (depth == 0){
        return (*state).evaluate();
    }
    Move moveList[256];
    int countMoves = (*state).genLegalMoves(moveList);

    if(countMoves == 0) { // Game has ended
        if((*state)._turn == WHITE) {  // White lost or draw
            Move helpList[1];
            helpList[0] = Move(4, 4, 4, 4); // Move does nothing
            int helpCountMoves = 1;
            (*state).isCheckW(helpList, &helpCountMoves);
            if(helpCountMoves == 0) { // White has lost
                return -1000;
            } else { // Draw
                return 0;
            }
        } else { // Black lost or draw
            Move helpList[1];
            helpList[0] = Move(4, 4, 4, 4); // Move does nothing
            int helpCountMoves = 1;
            (*state).isCheckB(helpList, &helpCountMoves);
            if(helpCountMoves == 0) { // Black has lost
                return 1000;
            } else { // Draw
                return 0;
            }
        }
    }

    double score;
    for (int i = 0 ; i < countMoves ; ++i){
        BoardState helpState = (*state).clone();
        bool captured;
        captured = helpState.execMove(moveList[i]);
        if(depth == 100) { //depth has been modified before
            score = alphaBetaMin(alpha, beta, 0, &helpState);
        } else if(captured == true && depth == 1){
            score = alphaBetaMin(alpha, beta, 100, &helpState);
        } else {
            score = alphaBetaMin(alpha, beta, depth-1, &helpState);
        }
        if (score >= beta){
            return beta;
        } else if (score > alpha){
            alpha = score;
        }
    }
    return alpha;
}

double BoardState::alphaBetaMin(int alpha, int beta, int depth, BoardState *state){
    if (depth == 0){
        return (*state).evaluate();
    }
    Move moveList[256];
    int countMoves = (*state).genLegalMoves(moveList);

    if(countMoves == 0) { // Game has ended
        if((*state)._turn == WHITE) {  // White lost or draw
            Move helpList[1];
            helpList[0] = Move(4, 4, 4, 4); // Move does nothing
            int helpCountMoves = 1;
            (*state).isCheckW(helpList, &helpCountMoves);
            if(helpCountMoves == 0) { // White has lost
                return -1000;
            } else { // Draw
                return 0;
            }
        } else { // Black lost or draw
            Move helpList[1];
            helpList[0] = Move(4, 4, 4, 4); // Move does nothing
            int helpCountMoves = 1;
            (*state).isCheckB(helpList, &helpCountMoves);
            if(helpCountMoves == 0) { // Black has lost
                return 1000;
            } else { // Draw
                return 0;
            }
        }
    }

    double score;
    for (int i = 0 ; i < countMoves ; ++i){
        BoardState helpState = (*state).clone();
        bool captured;
        captured = helpState.execMove(moveList[i]);
        if(depth == 100) { //depth has been modified before
            score = alphaBetaMax(alpha, beta, 0, &helpState);
        } else if(captured == true && depth == 1){
            score = alphaBetaMax(alpha, beta, 100, &helpState);
        } else {
            score = alphaBetaMax(alpha, beta, depth-1, &helpState);
        }
        if (score <= alpha){
            return alpha;
        } else if (score < beta){
            beta = score;
        }
    }
    return beta;
}

double BoardState::evaluate(){
    double score = 0;
    score += evaluateMaterial() * 0.93;
    score += evaluatePosition() * 0.064;
    score += evaluateKingSafety() * 0.006;

    if(score < -999){
        return -999;
    } else if(score > 999){
        return 999;
    } else {
        return score;
    }
}

int BoardState::evaluateMaterial(){
    int score = 0;
    int w_pieces = 0, b_pieces = 0;
    int w_rooks = 0, b_rooks = 0;
    int w_bishops = 0, b_bishops = 0;
    for (int y=0; y<8; ++y){
        for (int x=0; x<8; ++x){
            if (_board[x][y] == W_PAWN) {score += 10;w_pieces++;}
            else if (_board[x][y] == B_PAWN) {score -= 10;b_pieces++;}
            else if (_board[x][y] == W_ROOK) {score += 50;w_rooks++;w_pieces++;}
            else if (_board[x][y] == W_KNIGHT) {score += 30;w_pieces++;}
            else if (_board[x][y] == W_BISHOP) {score += 30;w_bishops++;w_pieces++;}
            else if (_board[x][y] == W_QUEEN) {score += 90;w_pieces++;}
            else if (_board[x][y] == B_ROOK) {score -= 50;b_rooks++;b_pieces++;}
            else if (_board[x][y] == B_KNIGHT) {score -= 30;b_pieces++;}
            else if (_board[x][y] == B_BISHOP) {score -= 30;b_bishops++;b_pieces++;}
            else if (_board[x][y] == B_QUEEN) {score -= 90;b_pieces++;}
        }
    }

    // bonus from piece amount
    if (w_pieces+b_pieces < 19){
        score += w_pieces*2;
        score -= b_pieces*2;
    } else {
        score += w_pieces;
        score -= b_pieces;
    }

    // not so valuable if
    if (w_rooks == 2){score -= 2;}
    if (b_rooks == 2){score += 2;}

    //more valuable if
    if (w_bishops == 2){score += 3;}
    if (b_bishops == 2){score -= 3;}

    if(score < -999){
        return -999;
    } else if(score > 999){
        return 999;
    } else {
        return score;
    }
}

int BoardState::evaluateKingSafety(){
    int score = 0;
    if(_board[1][0] == B_KING){
        score -= 50;
    }
    else if(_board[6][0] == B_KING){
        score -= 50;
    }
    else if(_board[1][7] == W_KING){
        score += 50;
    }
    else if(_board[6][7] == W_KING){
        score += 50;
    }
    for (int y=0; y<8; ++y){
        for (int x=0; x<8; ++x){
            //plus for black
            if(_board[x][y] == B_KING && y < 7){
                if(x > 0){
                    if(_board[x-1][y+1] == B_PAWN){
                        score -= 50;
                    }
                }
                else if(_board[x][y+1] == B_PAWN){
                    score -= 50;
                }
                if(x < 7){
                    if(_board[x+1][y+1] == B_PAWN){
                        score -= 50;
                    }
                }
                else if(_board[x-1][y+1] == B_PAWN && _board[x][y+1] == B_PAWN
                   && _board[x+1][y+1] == B_PAWN){
                    score -= 700;
                }
                if(y < 6){
                    if(_board[x-1][y+1] == B_PAWN && _board[x][y+2] == B_PAWN
                       && _board[x+1][y+1] == B_PAWN){
                        score -= 700;
                    }
                }
            }
            //plus for white
            if(_board[x][y] == W_KING && y > 0){
                if(x > 0){
                    if(_board[x-1][y-1] == W_PAWN){
                        score += 50;
                    }
                }
                else if(_board[x][y-1] == W_PAWN){
                    score += 50;
                }
                if(x < 7){
                    if(_board[x+1][y-1] == W_PAWN){
                        score += 50;
                    }
                }
                else if(_board[x-1][y-1] == W_PAWN && _board[x][y-1] == W_PAWN
                   && _board[x+1][y-1] == W_PAWN){
                    score += 700;
                }
                if(y > 1){
                    if(_board[x-1][y-1] == W_PAWN && _board[x][y-2] == W_PAWN
                       && _board[x+1][y-1] == W_PAWN){
                        score += 700;
                    }
                }
            }
        }
    }

    //returns integer between -999 - 999
    // -999 = situation is mutch better for black
    // 999 = situation is mutch better for white
    if(score < -999){
        return -999;
    }
    else if( score > 999){
        return 999;
    }
    else{
        if(score > 0 && score < 100){
            return 100;
        }
        return score;
    }
}

int BoardState::evaluatePosition(){
int wAmount = 0, bAmount = 0;
    int wValue = 0, bValue = 0;
    int score;
    for (int y=0; y<8; ++y){
        for (int x=0; x<8; ++x){
            if (_board[x][y] != EMPTY){
                if (_board[x][y] == W_PAWN) {
                    wValue += posPawn[x][y];
                    wAmount++;
                } else if (_board[x][y] == B_PAWN) {
                    bValue += posPawn[x][7-y];
                    bAmount++;
                } else if (_board[x][y] == W_ROOK) {
                    wValue += posRook[x][y];
                    wAmount++;
                } else if (_board[x][y] == W_KNIGHT) {
                    wValue += posKnight[x][y];
                    wAmount++;
                } else if (_board[x][y] == W_BISHOP) {
                    wValue += posBishop[x][y];
                    wAmount++;
                } else if (_board[x][y] == W_QUEEN) {
                    wValue += posQueen[x][y];
                    wAmount++;
                } else if (_board[x][y] == B_ROOK) {
                    bValue += posRook[x][7-y];
                    bAmount++;
                } else if (_board[x][y] == B_KNIGHT) {
                    bValue += posKnight[x][7-y];
                    bAmount++;
                } else if (_board[x][y] == B_BISHOP) {
                    bValue += posBishop[x][7-y];
                    bAmount++;
                } else if (_board[x][y] == B_QUEEN) {
                    bValue += posQueen[x][7-y];
                    bAmount++;
                } else if (_board[x][y] == W_KING) {
                    wValue += posKing[x][y];
                    wAmount++;
                } else if (_board[x][y] == B_KING) {
                    bValue += posKing[x][7-y];
                    bAmount++;
                }
            }
        }
    }
    wValue = wValue / wAmount;
    bValue = bValue / bAmount;
    score = (wValue - bValue) * 10;
    if(score < -999){
        return -999;
    } else if(score > 999){
        return 999;
    } else {
        return score;
    }
}

const int BoardState::posPawn[8][8] = {
    { 50, 50, 50, 50, 50, 50, 50, 50},
    { 30, 30, 40, 50, 50, 40, 30, 30},
    { 10, 10, 20, 30, 30, 20, 10, 10},
    {  5,  5, 10, 25, 25, 10,  5,  5},
    {  0,  0,  0, 20, 20,  0,  0,  0},
    {  5, -5,-10,  0,  0, -10,-5,  5},
    {  5, 10, 10,-20,-20, 10, 10,  5},
    {  0,  0,  0,  0,  0,  0,  0,  0}
};

const int BoardState::posKnight[8][8] = {
    {-50,-49,-30,-30,-30,-30,-49,-50},
    {-40,-20,  0,  0,  0,  0,-20,-40},
    {-30,  0, 24, 25, 25, 24,  0,-30},
    {-30,  5, 25, 26, 26, 25,  5,-30},
    {-30,  0, 25, 26, 26, 25,  0,-30},
    {-30,  5, 24, 25, 25, 24,  5,-30},
    {-40,-20,  0,  5,  5,  0,-20,-40},
    {-50,-49,-30,-30,-30,-30,-49,-50}
};

const int BoardState::posBishop[8][8] = {
    {-20,-10,-10,-10,-10,-10,-10,-20},
    {-10,  0,  0,  0,  0,  0,  0,-10},
    {-10,  0, 10, 20, 20, 10,  0,-10},
    {-10,  5, 10, 20, 20, 10,  5,-10},
    {-10,  0, 20, 20, 20, 20,  0,-10},
    {-10, 20, 20, 20, 20, 20, 20,-10},
    {-10, 10,  0,  0,  0,  0, 10,-10},
    {-20,-10,-10,-10,-10,-10,-10,-20}
};

const int BoardState::posRook[8][8] = {
    {  0,  0,  0,  0,  0,  0,  0,  0},
    { 10, 20, 20, 20, 20, 20, 20, 10},
    {-10,  0,  0,  0,  0,  0,  0,-10},
    {-10,  0,  0,  0,  0,  0,  0,-10},
    {-10,  0,  0,  0,  0,  0,  0,-10},
    {-10,  0,  0,  0,  0,  0,  0,-10},
    {-10,  0,  0,  0,  0,  0,  0,-10},
    {  0,  0,  0, 10, 10,  0,  0,  0}
};

const int BoardState::posQueen[8][8] = {
    {-40,-20,-20,  0,  0,-20,-20,-40},
    {-20, 10, 10, 10, 10, 10, 10,-20},
    {-20, 10, 20, 20, 20, 20, 10,-20},
    {  0, 10, 20, 20, 20, 20, 10,  0},
    {  0, 10, 20, 20, 20, 20, 10,  0},
    {-20, 10, 20, 20, 20, 20, 10,-20},
    {-20, 10, 20, 10, 10, 20, 10,-20},
    {-40,-20,-20,  0,  0,-20,-20,-40}
};

const int BoardState::posKing[8][8] = {
    {-50,-50,-50,-45,-45,-50,-50,-50},
    {-50,-45,-45,-45,-45,-45,-45,-50},
    {-50,-40,-40,-40,-40,-40,-40,-50},
    {-50,-40,-35,-35,-35,-35,-40,-50},
    {-45,-35,-30,-20,-20,-30,-35,-45},
    {-45,-40, 10, 10, 10,-30,-40,-45},
    {-45,-30,-15,-15, 10,-30,-30,-45},
    {-50, 50,-10, 30,-10, 50,-40,-50}
};
